package com.cloud.school.app.service.impl;

import com.cloud.school.app.entity.TbGroupMember;
import com.cloud.school.app.mapstruct.IGroupMemberConvertMapper;
import com.cloud.school.app.model.GroupMemberModel;
import com.cloud.school.app.model.GroupModel;
import com.cloud.school.app.model.UserModel;
import com.cloud.school.app.repository.TbGroupMemberMapper;
import com.cloud.school.app.service.GroupMemberService;
import com.cloud.school.app.service.GroupService;
import com.cloud.school.app.service.UserService;
import com.cloud.school.app.util.IdWorker;
import com.cloud.school.app.util.enumeration.GroupMemberStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @ClassName GroupMemberServiceImpl
 * @Description TODO
 * @Author 36297
 * @Date 2018/12/13 20:16
 * @Version 1.0
 */
@Service
public class GroupMemberServiceImpl implements GroupMemberService {

    @Autowired
    private TbGroupMemberMapper tbGroupMemberMapper;
    @Autowired
    private IGroupMemberConvertMapper groupMemberConvertMapper;
    @Autowired
    private IdWorker groupMemberIdWorker;
    @Autowired
    private UserService userService;
    @Autowired
    private GroupService groupService;

    @Override
    public List<GroupMemberModel> queryByGroupId(Long groupId) {
        TbGroupMember query = new TbGroupMember();
        query.setGroupId(groupId);
        query.setStatus(GroupMemberStatus.HANDLED.getCode());
        return groupMemberConvertMapper.entityToModel(tbGroupMemberMapper.select(query));
    }

    @Override
    @Transactional
    public boolean save(List<GroupMemberModel> groupMemberModels) {
        List<TbGroupMember> groupMembers = groupMemberConvertMapper.modelToEntity(groupMemberModels);
        groupMembers.forEach(g -> g.setId(groupMemberIdWorker.nextId()));
        return tbGroupMemberMapper.batchInsert(groupMembers) > 0;
    }

    private void appendUser(List<GroupMemberModel> result) {
        List<Long> uids = result.stream().map(g -> g.getUserId()).filter(id -> id != null).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(uids)) {
            Map<Long, UserModel> userModelMap = userService.queryByIds(uids).stream().collect(Collectors.toMap(UserModel::getId, u -> u));
            result.forEach(g -> g.setUserModel(userModelMap.get(g.getUserId())));
        }
    }

    @Override
    @Transactional
    public boolean save(GroupMemberModel groupMemberModel) {
        TbGroupMember groupMember = groupMemberConvertMapper.modelToEntity(groupMemberModel);
        groupMember.setId(groupMemberIdWorker.nextId());
        return tbGroupMemberMapper.insertSelective(groupMember) > 0;
    }

    @Override
    @Transactional
    public boolean deleteByGroupIdAndUserIds(Long groupId, List<Long> userIds) {
        Example example = new Example(TbGroupMember.class);
        example.createCriteria().andEqualTo("groupId", groupId).andIn("userId", userIds);
        return tbGroupMemberMapper.deleteByExample(example) > 0;
    }

    @Override
    @Transactional
    public boolean inviteUser(Long groupId, List<Long> userIds, Long inviteUid) {
        GroupModel groupModel = groupService.selectByPrimaryKey(groupId);
        String groupName = groupModel == null ? "" : groupModel.getName();
        List<GroupMemberModel> groupMemberModels = userIds.stream().map(userId -> {
            GroupMemberModel groupMemberModel = new GroupMemberModel();
            groupMemberModel.setInviteTime(System.currentTimeMillis());
            groupMemberModel.setUserId(userId);
            groupMemberModel.setInviteUid(inviteUid);
            groupMemberModel.setGroupId(groupId);
            groupMemberModel.setGroupName(groupName);
            groupMemberModel.setStatus(GroupMemberStatus.UNHANDLED.getCode());
            return groupMemberModel;
        }).collect(Collectors.toList());
        return save(groupMemberModels);
    }

    @Override
    @Transactional
    public boolean passInvitation(Long groupMemberId) {
        TbGroupMember groupMember = new TbGroupMember();
        groupMember.setStatus(GroupMemberStatus.HANDLED.getCode());
        groupMember.setId(groupMemberId);
        return tbGroupMemberMapper.updateByPrimaryKeySelective(groupMember) > 0;
    }

    @Override
    public List<GroupMemberModel> queryInvitation(Long userId) {
        TbGroupMember query = new TbGroupMember();
        query.setUserId(userId);
        query.setStatus(GroupMemberStatus.UNHANDLED.getCode());
        List<GroupMemberModel> result = groupMemberConvertMapper.entityToModel(tbGroupMemberMapper.select(query));
        appendUser(result);
        return result;
    }

    @Override
    public List<GroupMemberModel> queryDetailByGroupId(Long groupId) {
        List<GroupMemberModel> result = queryByGroupId(groupId);
        appendUser(result);
        return result;
    }
}
